<script setup lang="ts">
import {
  ElButton,
  ElDialog,
  ElForm,
  ElFormItem,
  ElInput,
  ElMessage,
  ElMessageBox,
  ElOption,
  ElSelect,
  FormInstance,
  FormRules,
} from 'element-plus';
import Table from '@/components/table/index.vue';
import useManageUser from './useManageUser';
import { addUserNode, editUserNode, deleteUser, resetUser, UserItem } from '@/services/user';

const authOptions = [
  { value: 3, label: '管理员' },
  { value: 2, label: '普通用户' },
];

const {
  list,
  getList,
  loading,
  total,
  page: pageNo,
  size: pageSize,
} = useManageUser();
const editRow = reactive({
  id: 0,
  username: '',
  roleId: 2,
  comment: '',
});
const editLoading = ref(false);
const editVisible = ref(false);
const resetLoading = ref(false);
const resetVisible = ref(false);
const formRef = ref<FormInstance>();
const rules = reactive<FormRules>({
  username: [
    { required: true, message: '请输入用户名', trigger: ['blur'] },
    { max: 30, message: '最长30位字符', trigger: ['change'] },
  ],
  roleId: [
    { required: true, message: '请选择角色权限', trigger: ['blur'] },
  ],
  comment: [
    { max: 200, message: '最长200位字符', trigger: ['change'] },
  ],
});
const resetRow = reactive({
  id: 0,
  password: '',
  username: '',
});
const resetFormRef = ref<FormInstance>();
const resetRules = {
  password: [
    { required: true, message: '密码不能为空！', trigger: ['blur','change'] },
    { min: 6, message: '密码至少为6位', trigger: ['change'] },
    { max: 20, message: '密码最多为20位', trigger: ['change'] },
  ],
};

const handleQuery = (pn: number, ps: number) => {
  getList({ pn, ps });
};

const handleDeleteRow = async (row: UserItem) => {
  await ElMessageBox.confirm(`确定删除账号“${row.username}”吗？`, '删除账号', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'info',
    closeOnClickModal: false,
  });
  try {
    await deleteUser({ ids: String(row.id) });
    ElMessage({
      type: 'success',
      message: '操作成功',
    });
    handleQuery(1, pageSize.value);
  } catch {
    ElMessage({
      type: 'warning',
      message: '操作失败，请重试',
    });
  }
};

const handleResetRow = async () => {
  const valid = await resetFormRef.value?.validate();
  if (!valid) return;
  try {
    await resetUser({
      id: resetRow.id,
      password: resetRow.password,
    });
    ElMessage({
      type: 'success',
      message: '重置密码成功',
    });
    resetVisible.value = false;
    handleQuery(1, pageSize.value);
  } catch {
    ElMessage({
      type: 'warning',
      message: '操作失败，请重试',
    });
  }
};

const showResetDialog = (row: UserItem) => {
  resetVisible.value = true;
  Object.assign(resetRow, {
    id: row.id,
    username: row.username,
    password: '',
  });
};

const showEditDialog = (row: UserItem) => {
  editVisible.value = true;
  formRef.value?.clearValidate();
  Object.assign(editRow, {
    id: row.id,
    username: row.username,
    roleId: row.roleIds.includes(3) ? 3 : 2,
    comment: row.comment,
  });
};

const showAddDialog = () => {
  formRef.value?.clearValidate();
  Object.assign(editRow, {
    id: 0,
    username: '',
    roleId: 2,
    comment: '',
  });
  editVisible.value = true;
};

const columns = [
  {
    prop: 'username',
    label: '用户名',
    align: 'center',
  },
  {
    prop: 'username',
    label: '角色权限',
    align: 'center',
    render: (columnsProps: { row: UserItem }) => {
      const role = columnsProps.row.roleIds?.includes(3) ? '管理员' : '普通用户';
      return h('span', null, role);
    },
  },
  // {
  //   prop: 'clearPasswd',
  //   label: '密码',
  //   align: 'center',
  // },
  {
    prop: 'comment',
    label: '备注',
    align: 'center',
    width: 200,
    render: (columnsProps: { row: UserItem }) => {
      const comment = columnsProps.row.comment || '--';
      return h('span', null, comment);
    },
  },
  {
    label: '操作',
    align: 'center',
    width: 200,
    // fixed: 'right',
    renderBtns: [
      { text: '编辑', onClick: (_idx: number, row: any) => showEditDialog(row), type: 'primary', link: true },
      { text: '删除', onClick: (_idx: number, row: any) => handleDeleteRow(row), type: 'danger', link: true },
      { text: '重置密码', onClick: (_idx: number, row: any) => showResetDialog(row), type: 'danger', link: true },
    ]
  },
];

const handleCancelReset = () => {
  resetVisible.value = false;
};

const handleCancelEdit = () => {
  editVisible.value = false;
};

const handleSaveEdit = async () => {
  const valid = await formRef.value?.validate();
  if (!valid) {
    return;
  }
  editLoading.value = true;
  try {
    const data = {
      username: editRow.username,
      roleIds: [editRow.roleId],
      comment: editRow.comment,
    };
    if (editRow.id === 0) {
      await addUserNode(data);
    } else {
      await editUserNode(editRow.id, data);
    }
    editVisible.value = false;
    ElMessage({
      type: 'success',
      message: '操作成功',
    });
  } catch(err) {
    ElMessage({
      type: 'warning',
      message: (err as Error).message || '操作失败，请重试',
    });
  } finally {
    handleQuery(1, pageSize.value);
    editLoading.value = false;
  }
};

onMounted(() => {
  handleQuery(1, pageSize.value);
});
</script>

<template>
  <div class="user-container config-page">
    <div class="page-title">
      <span>系统设置</span>
      <span> / </span>
      <span class="page-title-active">用户管理</span>
    </div>
    <div class="page-query">
      <ElForm :inline="true">
        <ElFormItem>
          <ElButton type="primary" @click="() => showAddDialog()">+ 添加账号</ElButton>
        </ElFormItem>
      </ElForm>
    </div>
    <div class="page-table-container">
      <Table
        :loading="loading"
        :list="list"
        height="calc(100vh - 35px - 62px - 50px - 40px - 60px)"
        :columns="columns"
        :total="total"
        :page-no="pageNo"
        :page-size="pageSize"
        :get-list="(pageNo: number, pageSize: number) => handleQuery(pageNo, pageSize)"
      />
    </div>
    <ElDialog
      class="custom-dialog"
      v-model="editVisible"
      :title="editRow.id ? '编辑账号' : '添加账号'"
      width="560"
      align-center
      :close-on-click-modal="false"
    >
      <ElForm ref="formRef" :rules="rules" :model="editRow" label-width="90">
        <!-- <ElFormItem prop="name" label="账号">
          <ElInput placeholder="请输入账号" v-model="editRow.name" />
        </ElFormItem> -->
        <ElFormItem prop="username" label="用户名">
          <ElInput placeholder="请输入用户名" v-model.trim="editRow.username" />
        </ElFormItem>
        <ElFormItem prop="roleId" label="角色权限">
          <ElSelect
            v-model="editRow.roleId"
            popper-class="custom-select-popper"
            placeholder="请选择角色权限"
          >
            <ElOption
              v-for="option in authOptions"
              :key="option.value"
              :value="option.value"
              :label="option.label"
            />
          </ElSelect>
        </ElFormItem>
        <ElFormItem prop="comment" label="备注">
          <ElInput placeholder="请输入备注" v-model="editRow.comment" type="textarea" :rows="3" resize="none" />
        </ElFormItem>
      </ElForm>
      <div class="dialog-footer">
        <ElButton @click="() => handleCancelEdit()">取消</ElButton>
        <ElButton :loading="editLoading" type="primary" @click="() => handleSaveEdit()">保存</ElButton>
      </div>
    </ElDialog>
    <ElDialog
      class="custom-dialog"
      v-model="resetVisible"
      title="重置密码"
      width="560"
      align-center
      :close-on-click-modal="false"
    >
      <ElForm ref="resetFormRef" :rules="resetRules" :model="resetRow" label-width="90">
        <ElFormItem prop="username" label="用户名">
          <ElInput placeholder="请输入用户名" v-model="resetRow.username" disabled />
        </ElFormItem>
        <ElFormItem prop="password" label="新密码">
          <ElInput type="password" placeholder="请输入新密码" v-model.trim="resetRow.password" />
        </ElFormItem>
      </ElForm>
      <div class="dialog-footer">
        <ElButton @click="() => handleCancelReset()">取消</ElButton>
        <ElButton :loading="resetLoading" type="primary" @click="() => handleResetRow()">保存</ElButton>
      </div>
    </ElDialog>
  </div>
</template>

<style scoped>
</style>

<style lang="less">
.record {
  padding: 20px;
}
</style>
